/**
 * Copyright 2024-2024 Huawei Technologies Co., Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef FRAMEWORK_C_MM_HIAI_MODEL_BUILD_OPTIONS_H
#define FRAMEWORK_C_MM_HIAI_MODEL_BUILD_OPTIONS_H

#include <stddef.h>

#include "c/hiai_c_api_export.h"
#include "c/hiai_error_types.h"
#include "c/hcl/hiai_types.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief 创建模型编译参数指针实例
 *
 * 该方法用于模型编译接口{@link HIAI_MR_ModelBuilder_Build}，需要设置模型编译参数{@link HIAI_MR_ModelBuildOptions}时，
 * 创建模型编译参数指针实例。模型编译完成后，模型编译参数{@link HIAI_MR_ModelBuildOptions}不再使用时，
 * 需要使用{@link HIAI_MR_ModelBuildOptions_Destroy}进行释放，否则将造成内存泄漏。
 *
 * @return 成功返回{@link HIAI_MR_ModelBuildOptions}指针，失败返回空指针
 */
AICP_C_API_EXPORT HIAI_MR_ModelBuildOptions* HIAI_MR_ModelBuildOptions_Create(void);

/**
 * @brief 释放模型编译参数
 *
 * 该方法用于释放{@link HIAI_MR_ModelBuildOptions_Create}创建的指针实例，若不调用，将造成内存泄漏。
 *
 * @param options {@link HIAI_MR_ModelBuildOptions}模型编译参数指针实例的引用，非空
 */
AICP_C_API_EXPORT void HIAI_MR_ModelBuildOptions_Destroy(HIAI_MR_ModelBuildOptions** options);

typedef enum {
    /** 格式为NCHW，默认值。 */
    HIAI_FORMAT_MODE_USE_NCHW = 0,
    /** 格式为原始模型格式。 */
    HIAI_FORMAT_MODE_USE_ORIGIN = 1
} HIAI_FORMAT_MODE_OPTION;

/**
 * @brief 设置模型编译时的数据排列格式。
 *
 * 本方法仅在模型编译阶段生效，用于模型中的数据排列格式与默认值不匹配时的场景。
 *
 * @param options {@link HIAI_MR_ModelBuildOptions}指针实例，非空。
 * @param formatMode 数据排列格式{@link HIAI_FORMAT_MODE_OPTION}。
 */
AICP_C_API_EXPORT void HIAI_MR_ModelBuildOptions_SetFormatModeOption(HIAI_MR_ModelBuildOptions* options,
    HIAI_FORMAT_MODE_OPTION formatMode);

/**
 * @brief 查询模型编译参数中的数据排列格式。
 *
 * @param compilation {@link HIAI_MR_ModelBuildOptions}指针实例，非空，否则返回默认值。
 * @return 成功返回 {@link HIAI_FORMAT_MODE_OPTION}，失败返回默认值。
 */
AICP_C_API_EXPORT HIAI_FORMAT_MODE_OPTION HIAI_MR_ModelBuildOptions_GetFormatModeOption(
    const HIAI_MR_ModelBuildOptions* options);

typedef enum {
    /** 精度为fp32 */
    HIAI_PRECISION_MODE_FP32 = 0,
    /** 精度为fp16 */
    HIAI_PRECISION_MODE_FP16
} HIAI_PRECISION_MODE_OPTION;

/**
 * @brief 设置模型编译参数中的精度模式
 *
 * @param [in] options {@link HIAI_MR_ModelBuildOptions}模型加载参数指针实例，非空
 * @param [in] precisionMode 精度模式，取值参见{@link HIAI_PRECISION_MODE_OPTION}
 * @return 函数执行结果状态。执行成功返回HIAI_SUCCESS；失败返回具体错误码，具体失败错误码可参考{@link HIAI_Status}
 */
AICP_C_API_EXPORT HIAI_Status HIAI_MR_ModelBuildOptions_SetPrecisionModeOption(HIAI_MR_ModelBuildOptions* options,
    HIAI_PRECISION_MODE_OPTION precisionMode);

/**
 * @brief 查询模型编译参数中的精度模式
 *
 * @param [in] options {@link HIAI_MR_ModelBuildOptions}模型加载参数指针实例，非空
 * @return 成功返回精度模式；失败返回{@link HIAI_PRECISION_MODE_FP32}
 */
AICP_C_API_EXPORT HIAI_PRECISION_MODE_OPTION HIAI_MR_ModelBuildOptions_GetPrecisionModeOption(
    const HIAI_MR_ModelBuildOptions* options);

/**
 * @brief 设置模型编译时量化配置。
 *
 * 本方法仅在模型编译阶段生效。用于模型编译时进行量化的场景。
 *
 * @param [in] options {@link HIAI_MR_ModelBuildOptions}指针实例，非空，否则返回失败。
 * @param [in] data 量化配置的数据地址，非空，否则返回失败。
 * @param [in] size 量化配置的数据大小，大于0，否则返回失败。
 * @return 函数执行结果状态。执行成功返回HIAI_SUCCESS；失败返回具体错误码，具体失败错误码可参考{@link HIAI_Status}
 */
AICP_C_API_EXPORT HIAI_Status HIAI_MR_ModelBuildOptions_SetQuantizeConfig(HIAI_MR_ModelBuildOptions* options,
    uint8_t* data, size_t size);

/**
 * @brief 查询量化配置的数据地址。
 *
 * @param options {@link HIAI_MR_ModelBuildOptions}指针实例，非空，否则返回空指针。
 * @return 成功返回量化配置的数据地址，失败返回空指针。
 */
AICP_C_API_EXPORT uint8_t* HIAI_MR_ModelBuildOptions_GetQuantizeConfigData(const HIAI_MR_ModelBuildOptions* options);

/**
 * @brief 查询量化配置的数据大小。
 *
 * @param options {@link HIAI_MR_ModelBuildOptions}指针实例，非空，否则返回0。
 * @return 成功返回量化配置的数据大小，失败返回0。
 */
AICP_C_API_EXPORT size_t HIAI_MR_ModelBuildOptions_GetQuantizeConfigSize(const HIAI_MR_ModelBuildOptions* options);

typedef enum {
    /** 不支持深度融合场景，也不支持编译前可变shape。 */
    HIAI_TUNING_STRATEGY_OFF = 0,
    /** 支持编译前可变shape场景深度融合优化模型。 */
    HIAI_TUNING_STRATEGY_ON_DEVICE_TUNING,
    /** NPU算子库动态升级场景深度融合优化模型。 */
    HIAI_TUNING_STRATEGY_ON_DEVICE_PREPROCESS_TUNING,
    /** 未来场景的预留，目前不使用。 */
    HIAI_TUNING_STRATEGY_ON_CLOUD_TUNING
} HIAI_TUNING_STRATEGY;

/**
 * @brief 设置模型编译参数中的调优策略
 *
 * @param [in] options {@link HIAI_MR_ModelBuildOptions}模型加载参数指针实例，非空
 * @param [in] tuningStrategy 调优策略，取值参见{@link HIAI_TUNING_STRATEGY}
 * @return 函数执行结果状态。执行成功返回HIAI_SUCCESS；失败返回具体错误码，具体失败错误码可参考{@link HIAI_Status}
 */
AICP_C_API_EXPORT HIAI_Status HIAI_MR_ModelBuildOptions_SetTuningStrategy(
    HIAI_MR_ModelBuildOptions* options, HIAI_TUNING_STRATEGY tuningStrategy);

/**
 * @brief 查询模型编译参数中的调优策略
 *
 * @param [in] options {@link HIAI_MR_ModelBuildOptions}模型加载参数指针实例，非空
 * @return 成功返回调优策略；失败返回{@link HIAI_TUNING_STRATEGY_OFF}
 */
AICP_C_API_EXPORT HIAI_TUNING_STRATEGY HIAI_MR_ModelBuildOptions_GetTuningStrategy(
    const HIAI_MR_ModelBuildOptions* options);

#ifdef __cplusplus
}
#endif

#endif // FRAMEWORK_C_MM_HIAI_MODEL_BUILD_OPTIONS_H
